﻿Imports System.IO
Imports System.Security.Cryptography
Imports TyranntEngine

Public Class uploaderForm

    Dim WithEvents db As New TyranntWelcomeService.WelcomeClient
    Private _token As String = ""
    Private _jobList As New GameFileCollection
    Private _localCollecton As New GameFileCollection
    Private _serverCollection As New GameFileCollection
    Private _errDlg As New ErrorDlg

    Private Sub updaterForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim openDialog As New OpenFileDialog
        openDialog.Title = "Select directory containing client files"
        openDialog.ShowDialog()
        System.IO.Directory.SetCurrentDirectory(Path.GetDirectoryName(openDialog.FileName))
        Dim login As New LogonControl
        If login.ShowDialog() = Windows.Forms.DialogResult.Cancel Then
            End
        End If
        _token = login.TokenString
        serverFilesGroupBox.Enabled = False
        clientFilesGroupBox.Enabled = False
        db.GetFilesAsync(_token)
    End Sub

    Private Sub db_GetFilesCompleted(ByVal sender As Object, ByVal e As TyranntWelcomeService.GetFilesCompletedEventArgs) Handles db.GetFilesCompleted
        If e.Result.Contains("[#]") Then
            _errDlg.ShowDialog(e.Result, "Get Files Failed")
        Else
            RefreshServerFiles(e.Result)
            RefreshClientFiles()
            GenerateJobList()
            DisplayLists()
            serverFilesGroupBox.Enabled = True
            clientFilesGroupBox.Enabled = True
        End If
    End Sub

    Private Sub DisplayLists()
        serverFilesListView.Items.Clear()
        For Each serverFile As GameFile In _serverCollection
            Dim item As New ListViewItem
            item.Text = serverFile.ID.ToString
            item.SubItems.Add(serverFile.Filename)
            item.SubItems.Add(serverFile.HashCode)
            If serverFile.Action <> "" Then
                Select Case serverFile.Action
                    Case "upload"
                        item.BackColor = Color.LightGreen
                    Case "delete"
                        item.BackColor = Color.LightSalmon
                    Case Else
                        item.BackColor = Color.Yellow
                End Select
            End If
            serverFilesListView.Items.Add(item)
        Next
        clientFilesListView.Items.Clear()
        For Each localFile As GameFile In _localCollecton
            Dim item As New ListViewItem
            item.Text = localFile.Filename
            item.SubItems.Add(localFile.HashCode)
            If localFile.Action <> "" Then
                Select Case localFile.Action
                    Case "upload"
                        item.BackColor = Color.LightGreen
                    Case "delete"
                        item.BackColor = Color.LightSalmon
                    Case Else
                        item.BackColor = Color.Yellow
                End Select
            End If
            clientFilesListView.Items.Add(item)
        Next
    End Sub

    Private Sub RefreshServerFiles(ByVal filesXML As String)
        Dim sr As New StringReader(filesXML)
        Dim filesX As XElement

        Try
            filesX = XElement.Load(sr)
        Catch ex As Exception
            Failed(filesXML, ex.ToString)
            Exit Sub
        End Try

        _serverCollection.Clear()
        Dim fileList = filesX...<file>
        For Each aFile In fileList
            Dim aGFile As New GameFile
            If Integer.TryParse(aFile.@id, aGFile.ID) = False Then
                MessageBox.Show(aFile.@id + " is not a valid integer", "Integer Conversion Failed", MessageBoxButtons.OK, MessageBoxIcon.Error)
                Exit Sub
            End If
            aGFile.Filename = aFile.<name>.Value
            If Long.TryParse(aFile.<size>.Value, aGFile.Size) = False Then
                aGFile.Size = 0
            End If
            aGFile.HashCode = aFile.<hash>.Value
            _serverCollection.Add(aGFile)
        Next
    End Sub

    Private Sub RefreshClientFiles()
        ' now check the local files
        Dim coreDir As New DirectoryInfo(".")
        Dim coreFiles() As FileInfo = coreDir.GetFiles()
        Dim mediaDir As New DirectoryInfo(".\media")
        Dim mediaFiles() As FileInfo = mediaDir.GetFiles
        _localCollecton.Clear()
        For Each aFile In coreFiles
            Dim addFile As Boolean = True
            If aFile.Name.EndsWith(".xml") Then
                addFile = False
            End If
            If aFile.Name.Contains(".vshost.") Then
                addFile = False
            End If
            If addFile = True Then
                Dim aGFile As New GameFile
                aGFile.Filename = ".\" + aFile.Name
                aGFile.Size = aFile.Length
                aGFile.HashCode = GetFileHash(aGFile.Filename)
                _localCollecton.Add(aGFile)
            End If
        Next
        For Each aFile In mediaFiles
            Dim aGFile As New GameFile
            aGFile.Filename = ".\media\" + aFile.Name
            aGFile.Size = aFile.Length
            aGFile.HashCode = GetFileHash(aGFile.Filename)
            _localCollecton.Add(aGFile)
        Next
    End Sub

    Private Sub GenerateJobList()
        ' Pass 1 work out what local files require uploading
        For Each localFile As GameFile In _localCollecton
            Dim foundLocal As Boolean = False
            For Each serverFile As GameFile In _serverCollection
                If serverFile.Filename = localFile.Filename Then
                    foundLocal = True
                    If localFile.HashCode <> serverFile.HashCode Then
                        localFile.Action = "upload"
                    End If
                    Exit For
                End If
            Next
            If foundLocal = False Then
                Dim addFile As Boolean = True
                If localFile.Filename.EndsWith(".pdb") Then
                    ' we are testing so add this file
                    addFile = True
                End If
                If addFile = True Then
                    localFile.Action = "upload"
                End If

            End If
        Next
        ' Pass 2 work out which server files require deleting
        For Each serverFile As GameFile In _serverCollection
            Dim foundServer As Boolean = False
            For Each localFile As GameFile In _localCollecton
                If localFile.Filename = serverFile.Filename Then
                    foundServer = True
                    Exit For
                End If
            Next
            If foundServer = False Then
                serverFile.Action = "delete"
            End If
        Next

        ' Generate list of jobs to do
        For Each serverFile As GameFile In _serverCollection
            If serverFile.Action <> "" Then
                _jobList.Add(serverFile)
            End If
        Next
        For Each localFile As GameFile In _localCollecton
            If localFile.Action <> "" Then
                _jobList.Add(localFile)
            End If
        Next
    End Sub

    Private Sub Failed(ByVal xmlString As String, ByVal ex As String)
        MessageBox.Show(xmlString + vbCrLf + vbCrLf + ex, "Failed to LoadXML", MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Sub

    Private Sub syncToolStripButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles syncToolStripButton.Click
        Dim transfer As New transferForm
        transfer.JobList = _jobList
        transfer.Token = _token
        transfer.ShowDialog()
        serverFilesGroupBox.Enabled = False
        clientFilesGroupBox.Enabled = False
        db.GetFilesAsync(_token)
    End Sub
End Class
